﻿using System;
using System.Collections.Generic;
using System.Security.AccessControl;
using System.Net;
using System.IO;
using System.Windows;
using System.Reflection;
using System.Security.Principal;
using System.ComponentModel;

namespace MAnt3
{
    /// <summary>
    /// Trida definuje veskerou praci s FTP
    /// </summary>
    class Ftp
    {
        #region VARIABLES
        private readonly IOproudy ioProudy;
        private List<Obrazek> seznamObrazku;
        private readonly BackgroundWorker PYTLIN;
        private Konfigurace konfigurece;
        private MainWindow mainWindow;
        #endregion

        #region CONSTRUCTORS
        public Ftp(MainWindow mw, IOproudy io, BackgroundWorker f, Konfigurace kon)
        {
            ioProudy = io;
            PYTLIN = f;
            konfigurece = kon;
            mainWindow = mw;
        }
        #endregion

        #region FTP UPLOAD
        /// <summary>
        /// nahraje obrazky na FTP
        /// </summary>
        /// <param name="cesta"></param>
        public void NahrajObrazkyNaFtp(string cesta)
        {
            // vypis
            PYTLIN.ReportProgress(6, "MSG");
            PYTLIN.ReportProgress(seznamObrazku.Count,"MAX");

            // pomocny seznam
            List<string> temp = new List<string>();
            bool b;

            foreach (Obrazek o in seznamObrazku)
            {
                b = true;

                // kontrola abych neukladal co uz tam je
                foreach (string s in temp)
                {
                    if (s.Equals(o.Cesta))
                    {
                        b = false;
                        break;
                    }
                }

                if (b)
                {
                    string ftpfilepath = konfigurece.Ftp1PathPictures + o.Nazev;

                    string ftpfullpath = string.Format(@"{0}{1}", konfigurece.Ftp1Host, ftpfilepath); 

                    Uri uri;
                    Uri.TryCreate(ftpfullpath, UriKind.RelativeOrAbsolute, out uri);
                    

                    try
                    {
                        FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(uri);

                        string u = konfigurece.Ftp1User;
                        string p = konfigurece.Ftp1Psw;
                        ftp.Credentials = new NetworkCredential(u, p);
                        ftp.KeepAlive = true;
                        ftp.UseBinary = true;
                        ftp.Method = WebRequestMethods.Ftp.UploadFile;

                        FileStream fs = File.OpenRead(@"" +cesta + "\\" + o.Nazev);
                        byte[] buffer = new byte[fs.Length];
                        fs.Read(buffer, 0, buffer.Length);
                        fs.Close();
                        Stream ftpstream = ftp.GetRequestStream();
                        ftpstream.Write(buffer, 0, buffer.Length);
                        ftpstream.Close();

                        temp.Add(o.Cesta);
                    }
                    catch (WebException e)
                    {
                        IOproudy.PridejChybu(MethodInfo.GetCurrentMethod().Name, e.ToString(), DateTime.Now);
                        return;
                    }
                }
                PYTLIN.ReportProgress(1, "INK");
            }
            PYTLIN.ReportProgress(3, "MSG");
        }

        /// <summary>
        /// nahraje XML soubory na FTP
        /// </summary>
        /// <param name="directoryPATH"></param>
        public void NahrajXmLnaFtp(string directoryPATH)
        {
            DirectoryInfo dInfo = new DirectoryInfo(directoryPATH);
            FileInfo[] seznam = dInfo.GetFiles();

            PYTLIN.ReportProgress(7, "MSG");
            PYTLIN.ReportProgress(5,"MAX");

            foreach (FileInfo f in seznam)
            {
                string ftpxmlpath   = konfigurece.Ftp1PathXml + f;
                string ftpfullpath = string.Format(@"{0}{1}", konfigurece.Ftp1Host, ftpxmlpath); 

                Uri uri;
                Uri.TryCreate(ftpfullpath, UriKind.RelativeOrAbsolute, out uri);

                try
                {
                    FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(uri);

                    ftp.Credentials = new NetworkCredential( konfigurece.Ftp1User, konfigurece.Ftp1Psw);
                    ftp.KeepAlive = true;
                    ftp.UseBinary = true;
                    ftp.Method = WebRequestMethods.Ftp.UploadFile;

                    FileStream fs = File.OpenRead(directoryPATH + "\\" + f);
                    byte[] buffer = new byte[fs.Length];
                    fs.Read(buffer, 0, buffer.Length);
                    fs.Close();
                    Stream ftpstream = ftp.GetRequestStream();
                    ftpstream.Write(buffer, 0, buffer.Length);
                    ftpstream.Close();
                }
                catch (WebException e)
                {
                    IOproudy.PridejChybu(MethodInfo.GetCurrentMethod().Name, e.ToString(), DateTime.Now);
                    return;
                }
                catch (UnauthorizedAccessException uae)
                {
                    IOproudy.PridejChybu(MethodInfo.GetCurrentMethod().Name, uae.ToString(), DateTime.Now);
                    return;
                }
                PYTLIN.ReportProgress(1, "INK");
            }
            PYTLIN.ReportProgress(3, "MSG");
        }

        /// <summary>
        /// provede upload souboru na FTP
        /// </summary>
        /// <param name="file">cesta k souboru</param>
        /// <param name="path">cil kopirovani</param>
        /// <param name="user">prihlasovaci jmeno na FTP</param>
        /// <param name="psw">heslo na FTP</param>
        public static void UploadFileOnFTP(string file, string path, string user, string psw)
        {
            Uri uri;
            Uri.TryCreate(path, UriKind.Absolute, out uri);
            try
            {
                FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(uri);

                ftp.Credentials = new NetworkCredential(user, psw);
                ftp.KeepAlive = true;
                ftp.UseBinary = true;
                ftp.Method = WebRequestMethods.Ftp.UploadFile;

                FileStream fs = File.OpenRead(file);
                byte[] buffer = new byte[fs.Length];
                fs.Read(buffer, 0, buffer.Length);
                fs.Close();
                Stream ftpstream = ftp.GetRequestStream();
                ftpstream.Write(buffer, 0, buffer.Length);
                ftpstream.Close();
            }
            catch (WebException e)
            {
                IOproudy.PridejChybu(MethodInfo.GetCurrentMethod().Name, e.ToString(), DateTime.Now);
                return;
            }
            catch (UnauthorizedAccessException uae)
            {
                IOproudy.PridejChybu(MethodInfo.GetCurrentMethod().Name, uae.ToString(), DateTime.Now);
                return;
            }
        }
        #endregion

        #region DOWNLOAD PICTURES
        
        /// <summary>
        /// stahne obrazky z webu
        /// </summary>
        /// <param name="seznam">seznam stahovanych souboru</param>
        /// <param name="cesta">ulozit do</param>
        public void StahniObrazky(List<Obrazek> seznam, string cesta)
        {
            // vypis
            PYTLIN.ReportProgress(seznam.Count, "VAL2");
            PYTLIN.ReportProgress(4,"MSG");
            PYTLIN.ReportProgress(seznam.Count, "MAX");

            // pred kazdym zavolanim metody radsi vytvorim novou instanci
            // protoze pri situaci kdy program neukoncim,ale pokracuji v novem importu by mohl nastat problem
            seznamObrazku = new List<Obrazek>();

            // pomocne promenne
            bool b;

            WebClient wc = new WebClient();

            // nastavim prava pro slozku 
            //try { AddDirectorySecurity(cesta, @"marwin", FileSystemRights.AppendData, AccessControlType.Allow); }
            //catch (Exception e){ Console.WriteLine(e); }

            try
            {
                foreach (Obrazek o in seznam)
                {
                    if(string.IsNullOrEmpty(o.Nazev))
                    {
                        break;
                    }

                    b = true;

                    // kontrola abych neukladal co uz tam je
                    foreach (Obrazek s in seznamObrazku)
                    {
                        if (s.Cesta.Equals(o.Cesta))
                        {
                            b = false;
                            break;
                        }
                    }

                    if (b)
                    {
                        try
                        {
                            wc.DownloadFile(o.Cesta, cesta + @"\" + o.Nazev);
                            seznamObrazku.Add(o);
                        }
                        catch (WebException e)
                        {
                            IOproudy.PridejChybu(MethodInfo.GetCurrentMethod().Name, e.ToString(), DateTime.Now);
                            //return;
                        }
                    }
                    PYTLIN.ReportProgress(1, "INK");
                }
            }
            catch (UnauthorizedAccessException ap) 
            {
                IOproudy.PridejChybu(MethodInfo.GetCurrentMethod().Name, ap.ToString(), DateTime.Now);
                return;
            }
            catch (WebException we) 
            {
                IOproudy.PridejChybu(MethodInfo.GetCurrentMethod().Name, we.ToString(), DateTime.Now);
                return;
            }
            PYTLIN.ReportProgress(3,"MSG");
        }
        
        #endregion

        #region POMOCNE METODY
        
        /// <summary>
        /// overi pripojeni k internetu
        /// </summary>
        /// <returns>vraci true pokud je pripojeni k dispozici</returns>
        public static bool OvereniPripojeni()
        {
            try
            {
                IPHostEntry objIPHE = Dns.GetHostEntry("www.seznam.cz");
                return true;
            }
            catch
            {
                return false;
            }
        }
        #endregion
    }
}